﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Ro.AssistFunction.BackNodeInfo;
using Ro.AssistFunction.TypeConversion;
using Ro.Common.RoArgs;
using Ro.Common.RoInterface.UserType;

namespace Ro.AssistFunction.SerializerChildNodes
{
    /// <summary>
    /// 新的解析一级子节点的方法
    /// </summary>
    public class NewSerChildNode
    {
        /// <summary>
        /// 临时方法
        /// </summary>
        private readonly XmlAndXElement _xmlAndXElement = new XmlAndXElement();

        /// <summary>
        /// 反馈Annotation信息给RoInitNodeToType
        /// </summary>
        /// <param name="sigNode">Annotation节点</param>
        /// <returns>Annotation信息</returns>
        public Annotation SerAnnotationNode(XmlNode sigNode)
        {
            Annotation annotation = new Annotation
            {
                //todo 无法理解为何这个地方引用的类也需要初始化
                Created = new AuthorDate(),
                LastUpdated = new AuthorDate()
            };

            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(sigNode);
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
            //赋值
            annotation.Description = (from des in xElement.Elements() where des.Name == tcs + "Description" select des).Single().Value;
            annotation.Created.Author = (from des in xElement.Elements() where des.Name == tcs + "Created" select des.Attribute(tcs + "Author")).Single().Value;
            annotation.Created.Date = (from des in xElement.Elements() where des.Name == tcs + "Created" select des.Attribute(tcs + "Date")).Single().Value;
            annotation.LastUpdated.Author = (from des in xElement.Elements() where des.Name == tcs + "LastUpdated" select des.Attribute(tcs + "Author")).Single().Value;
            annotation.LastUpdated.Date = (from des in xElement.Elements() where des.Name == tcs + "LastUpdated" select des.Attribute(tcs + "Date")).Single().Value;

            return annotation;
        }

        /// <summary>
        /// <para>反馈Properties信息给RoInitNodeToType</para>
        /// <para>Properties是TestConfig的首个节点</para>
        /// </summary>
        /// <param name="sigNode">Properties节点</param>
        /// <returns>返回List形式的Property列表</returns>
        public List<Property> SerPropertyNode(XmlNode sigNode)
        {
            //循环进行提取
            List<Property> backList = new List<Property>();

            foreach (XmlNode onePro in sigNode.ChildNodes)
            {
                //转换为XElement
                XElement xElement = _xmlAndXElement.ToXElement(onePro);

                //添加namespace
                XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
                //创建一个Property,但Description不参与设定
                Property oneProperty = new Property
                {
                    Id = (from des in xElement.Attributes() where des.Name == tcs + "ID" select des).Single().Value,
                    Value = (from des in xElement.Elements() where des.Name == tcs + "Value" select des).Single().Value,
                    //Description = (from des in xElement.Elements() where des.Name == tcs + "Description" select des).Single().Value
                };

                backList.Add(oneProperty);
            }

            return backList;
        }


        /// <summary>
        /// <para>反馈ConfigurationFile信息给RoInitNodeToType</para>
        /// <para>Imports是TestConfig的末个节点</para>
        /// </summary>
        /// <param name="sigNode">Imports节点</param>
        /// <returns>返回List形式的ConfigurationFile列表</returns>
        public List<ConfigurationFile> SerConfigurationFileNode(XmlNode sigNode)
        {
            //返回值
            List<ConfigurationFile> backList = new List<ConfigurationFile>();

            //循环进行提取
            foreach (XmlNode onePro in sigNode.ChildNodes)
            {
                //转换为XElement
                XElement xElement = _xmlAndXElement.ToXElement(onePro);
                //添加namespace
                XNamespace tcs = "http://tempuri.org/RoFramework.xsd";

                //赋值
                ConfigurationFile configurationFile = new ConfigurationFile
                {
                    Id = (from des in xElement.Attributes() where des.Name == tcs + "ID" select des).Single().Value,
                    Type = (from des in xElement.Attributes() where des.Name == tcs + "Type" select des).Single().Value,
                    Path = (from des in xElement.Elements() where des.Name == tcs + "Path" select des).Single().Value
                };

                backList.Add(configurationFile);
            }

            return backList;
        }


        /// <summary>
        /// <para>反馈AppInfo信息给RoInitNodeToType</para>
        /// <para>AppInfo是StartApp的单个子节点</para>
        /// </summary>
        /// <param name="sigNode">StartApp节点</param>
        /// <returns>AppInfo信息</returns>
        public AppInfo SerStartApp(XmlNode sigNode)
        {
            //appinfo节点
            XmlNode appnode = sigNode.FirstChild;

            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(appnode);
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
            //定义返回
            AppInfo appInfo = new AppInfo
            {
                AppName = (from des in xElement.Attributes() where des.Name == tcs + "AppName" select des).Single().Value,
                BaseWindowsBits = (from des in xElement.Elements() where des.Name == tcs + "BaseWindowsBits" select des).Single().Value,
                ExecuePath = (from des in xElement.Elements() where des.Name == tcs + "ExecuePath" select des).Single().Value
            };

            StringBuilder parBuilder = new StringBuilder();

            //定义参数XElement
            XElement parametersele = (from des in xElement.Elements() where des.Name == tcs + "Parameters" select des).Single();
            //提取Parameters下面所有的Parameter值，
            IEnumerable<XElement> list = from des in parametersele.Elements() where des.Name == tcs + "Parameter" select des;
            foreach (XElement variable in list)
            {
                if (variable.Value == string.Empty || variable.Value == "")
                {
                    appInfo.Parameters = null;
                    break;
                }
                parBuilder.Append(variable.Value + " ");
            }
            appInfo.Parameters = parBuilder.ToString();
            return appInfo;
        }


        /// <summary>
        /// <para>反馈closeApp信息给RoInitNodeToType</para>
        /// <para>closeApp是一级子节点</para>
        /// </summary>
        /// <param name="sigNode">closeApp节点</param>
        /// <returns>closeApp信息</returns>
        public CloseApp SerCloseApp(XmlNode sigNode)
        {
            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(sigNode);
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
            //定义返回
            CloseApp closeApp = new CloseApp
            {
                Keep = Convert.ToBoolean((from des in xElement.Attributes() where des.Name == tcs + "Keep" select des).Single().Value)
            };
            return closeApp;
        }


        /// <summary>
        /// <para>反馈LogFunction信息给RoInitNodeToType</para>
        /// <para>LogFunction是一级子节点</para>
        /// </summary>
        /// <param name="sigNode">closeApp节点</param>
        /// <returns>closeApp信息</returns>
        public LogFunction SerLogFunction(XmlNode sigNode)
        {
            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(sigNode);
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
            //定义返回
            LogFunction logFunction = new LogFunction
            {
                LogFilePath = (from des in xElement.Elements() where des.Name == tcs + "LogFilePath" select des).Single().Value
            };
            return logFunction;
        }


        /// <summary>
        /// 反馈TestcaseInfo信息给InterFuncCores
        /// </summary>
        /// <param name="sigNode">单个testcase节点</param>
        /// <returns>TestcaseInfo信息</returns>
        public TestcaseInfo SerTestcaseInfo(XmlNode sigNode)
        {
            //初始化
            TestcaseInfo testcaseInfo = new TestcaseInfo
            {
                TestCaseAnnotation = new Annotation(),
                TestSteps = new Queue<XmlNode>()
            };

            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(sigNode);
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";
            //给定Id
            testcaseInfo.TestCaseId = (from des in xElement.Attributes() where des.Name == tcs + "ID" select des).Single().Value;
            //获取annotation
            testcaseInfo.TestCaseAnnotation = SerAnnotationNode(sigNode.FirstChild);

            //提取TestSteps
            XElement stepXElement = (from des in xElement.Elements() where des.Name == tcs + "TestSteps" select des).Single();
            IEnumerable<XElement> all = stepXElement.Elements();
            //再转为XmlNode
            foreach (XElement variable in all)
            {
                XmlNode tempNode = _xmlAndXElement.ToXmlNode(variable);
                testcaseInfo.TestSteps.Enqueue(tempNode);
            }
            return testcaseInfo;
        }


        /// <summary>
        /// 反馈迭代测试信息给InterFuncCores
        /// </summary>
        /// <param name="sigNode"></param>
        /// <returns></returns>
        public IterationInfo SerIterationInfo(XmlNode sigNode)
        {
            IterationInfo iterationInfo = new IterationInfo
            {
                IterationList = new IterationList(),
                RepeatSteps = new Queue<XmlNode>()
            };
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";

            //转换为XElement
            XElement listele = _xmlAndXElement.ToXElement(sigNode.FirstChild);
            //给定Id
            iterationInfo.IterationList.Id = (from des in listele.Elements() where des.Name == tcs + "ListID" select des).Single().Value;

            //传输ListItems
            SpecalArgsIntoValue specalArgsIntoValue = new SpecalArgsIntoValue();
            iterationInfo.IterationList.UseListItems = specalArgsIntoValue.BackUseListArgs(iterationInfo.IterationList.Id);

            //写入步骤
            //转换为XElement
            XElement stepele = _xmlAndXElement.ToXElement(sigNode.LastChild);
            IEnumerable<XElement> all = stepele.Elements();
            //再转为XmlNode
            foreach (XElement variable in all)
            {
                XmlNode tempNode = _xmlAndXElement.ToXmlNode(variable);
                iterationInfo.RepeatSteps.Enqueue(tempNode);
            }

            //反馈值
            return iterationInfo;
        }


        /// <summary>
        /// 反馈循环测试信息给InterFuncCores
        /// </summary>
        /// <param name="sigNode"></param>
        /// <returns></returns>
        public RepeatInfo SerRepeatInfo(XmlNode sigNode)
        {
            RepeatInfo repeatInfo = new RepeatInfo();
            //添加namespace
            XNamespace tcs = "http://tempuri.org/RoFramework.xsd";

            //转换为XElement
            XElement xElement = _xmlAndXElement.ToXElement(sigNode);
            //给定Id
            repeatInfo.Counter = Convert.ToInt32((from des in xElement.Attributes() where des.Name == tcs + "Counter" select des).Single().Value);

            //写入步骤
            //转换为XElement
            XElement stepele = _xmlAndXElement.ToXElement(sigNode.FirstChild);
            IEnumerable<XElement> all = stepele.Elements();
            //再转为XmlNode
            foreach (XElement variable in all)
            {
                XmlNode tempNode = _xmlAndXElement.ToXmlNode(variable);
                repeatInfo.RepeatSteps.Enqueue(tempNode);
            }

            //反馈值
            return repeatInfo;
        }


        /// <summary>
        /// 返回一个GuiUseType，包含所有tcc文件中的所有信息
        /// </summary>
        /// <param name="tccfolderpath">选择的tcs文件夹路径</param>
        public GuiTccInfo SerGuiTccInfo(string tccfolderpath)
        {
            _reConfLangs = new List<ConfLangs>();
            _reConfProperties = new List<Property>();
            _reConfLists = new List<ConfLists>();
            _reConfMacros = new List<ConfMacros>();
            //Todo 重新更改方法，无法保证整个config文件夹中只有一个config文件，所有需要通过循环给定的方式，将config文件夹内的所有文件信息给到对应的List中

            //循环获取文件夹中的文件
            DirectoryInfo theFolder = new DirectoryInfo(tccfolderpath);
            FileInfo[] fileInfos = theFolder.GetFiles();
            foreach (FileInfo sigfile in fileInfos)
            {
                string path = sigfile.FullName;
                //定义tcs文件根元素
                string tcsroot = "//conf:Config";

                //创建 xmldoc
                XmlDocument texDoc = new XmlDocument();

                //忽略注释
                XmlReaderSettings settings = new XmlReaderSettings {IgnoreComments = true};
                XmlReader reader = XmlReader.Create(path, settings); //创建读取类
                texDoc.Load(reader);

                //添加前缀
                XmlNamespaceManager xmlsManager = new XmlNamespaceManager(texDoc.NameTable);
                xmlsManager.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema");
                xmlsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
                xmlsManager.AddNamespace("conf", "http://tempuri.org/RoConfig.xsd");
                xmlsManager.AddNamespace("web", "http://tempuri.org/RoWebAutomation.xsd");
                xmlsManager.AddNamespace("tcs", "http://tempuri.org/RoFramework.xsd");
                //根节点
                XmlNode tccRootNode = texDoc.SelectSingleNode(tcsroot, xmlsManager);
                SingleTccFile(tccRootNode);
            }

            //初始化返回值
            GuiTccInfo guiTccInfo = new GuiTccInfo
            {
                GuiConfLangs = _reConfLangs,
                GuiConfLists = _reConfLists,
                GuiMacros = _reConfMacros,
                GuiProperties = _reConfProperties
            };

            return guiTccInfo;
        }


        /*##############################################私有方法########################################################*/


        /// <summary>
        /// Tcc文件中的Langs相关信息
        /// </summary>
        private List<ConfLangs> _reConfLangs;


        /// <summary>
        /// Tcc文件中的property相关信息
        /// </summary>
        private List<Property> _reConfProperties;


        /// <summary>
        /// Tcc文件中的Lists相关信息
        /// </summary>
        private List<ConfLists> _reConfLists;


        /// <summary>
        /// Tcc文件中的Macros相关信息
        /// </summary>
        private List<ConfMacros> _reConfMacros;


        /// <summary>
        /// 私有方法，处理单一的tcc文件，将文件中的所有的信息均给定到对应的list中
        /// </summary>
        /// <param name="rootNode">单一tcc文件的根节点</param>
        private void SingleTccFile(XmlNode rootNode)
        {
            //获取所有子节点
            XmlNodeList childNodes = rootNode.ChildNodes;
            //循环给值
            foreach (XmlNode sigNode in childNodes)
            {
                //判断给值
                switch (sigNode.Name)
                {
                    case "conf:Macros":
                        foreach (XmlNode onePro in sigNode.ChildNodes)
                        {
                            //转换为XElement
                            XElement xElement = _xmlAndXElement.ToXElement(onePro);

                            //添加namespace
                            XNamespace confg = "http://tempuri.org/RoConfig.xsd";

                            ConfMacros oneMacros = new ConfMacros
                            {
                                MacroId = (from des in xElement.Attributes() where des.Name == confg + "ID" select des).Single().Value,
                                MacroSteps = _xmlAndXElement.ToXmlNode((from des in xElement.Elements() where des.Name == confg + "MacroActivities" select des).Single()),
                            };

                            _reConfMacros.Add(oneMacros);
                        }
                        break;

                    case "conf:Lists":
                        foreach (XmlNode onePro in sigNode.ChildNodes)
                        {
                            //转换为XElement
                            XElement xElement = _xmlAndXElement.ToXElement(onePro);

                            //添加namespace
                            XNamespace confg = "http://tempuri.org/RoConfig.xsd";

                            ConfLists oneConfLists = new ConfLists
                            {
                                ListId = (from des in xElement.Attributes() where des.Name == confg + "ID" select des).Single().Value,
                            };

                            //给定value值
                            XElement a = (from des in xElement.Elements() where des.Name == confg + "ListItems" select des).Single();
                            foreach (XElement sigElement in a.Elements())
                            {
                                oneConfLists.ListItem.Enqueue(sigElement.Value);
                            }

                            _reConfLists.Add(oneConfLists);
                        }
                        break;

                    case "conf:Properties":
                        //插入
                        _reConfProperties.AddRange(SerPropertyNode(sigNode));
                        break;

                    case "conf:Languages":
                        foreach (XmlNode onePro in sigNode.ChildNodes)
                        {
                            //转换为XElement
                            XElement xElement = _xmlAndXElement.ToXElement(onePro);

                            //添加namespace
                            XNamespace confg = "http://tempuri.org/RoConfig.xsd";

                            ConfLangs oneConfLangs = new ConfLangs
                            {
                                LangId = (from des in xElement.Attributes() where des.Name == confg + "ID" select des).Single().Value,
                            };

                            //给定value值
                            XElement a = (from des in xElement.Elements() where des.Name == confg + "LangItems" select des).Single();
                            foreach (XElement sigElement in a.Elements())
                            {
                                oneConfLangs.LangValue.Add(sigElement.Value);
                            }
                            _reConfLangs.Add(oneConfLangs);
                        }
                        break;
                }
            }
        }
    }
}
  